package com.ruoyi.web.controller.system;

import java.util.List;
import java.util.stream.Collectors;

import com.ruoyi.common.annotation.ApiEncrypt;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.*;
import com.ruoyi.web.controller.dto.HospitalImportDto;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;

/**
 * 用户信息
 * 
 * @author ruoyi
 */
@ApiEncrypt
@Controller
@RequestMapping("/system/user")
public class SysUserController extends BaseController
{
    private String prefix = "system/user";

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysUserRoleService userRoleService;
    
    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private ISysPostService postService;

    @Autowired
    private SysPasswordService passwordService;

    @RequiresPermissions("system:user:view")
    @GetMapping()
    public String user()
    {
        return prefix + "/user";
    }

    @RequiresPermissions("system:user:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(SysUser user)
    {
        startPage();
        List<SysUser> list = userService.selectUserList(user);
        return getDataTable(list);
    }

    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
    @RequiresPermissions("system:user:export")
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(SysUser user)
    {
        List<SysUser> list = userService.selectUserList(user);
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        return util.exportExcel(list, "用户数据");
    }

    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
    @RequiresPermissions("system:user:import")
    @PostMapping("/importData")
    @ResponseBody
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        List<SysUser> userList = util.importExcel(file.getInputStream());
        String message = userService.importUser(userList, updateSupport, getLoginName());
        return AjaxResult.success(message);
    }

    @RequiresPermissions("system:user:view")
    @GetMapping("/importTemplate")
    @ResponseBody
    public AjaxResult importTemplate()
    {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        return util.importTemplateExcel("用户数据");
    }

    /**
     * 新增用户
     */
    @RequiresPermissions("system:user:add")
    @GetMapping("/add")
    public String add(ModelMap mmap)
    {
        mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        mmap.put("posts", postService.selectPostAll());
        return prefix + "/add";
    }

    /**
     * 新增保存用户
     */
    @RequiresPermissions("system:user:add")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(@Validated SysUser user)
    {
        deptService.checkDeptDataScope(user.getDeptId());
        roleService.checkRoleDataScope(user.getRoleIds());
        if (!userService.checkLoginNameUnique(user))
        {
            return error("新增用户'" + user.getLoginName() + "'失败，登录账号已存在");
        }
        else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
        {
            return error("新增用户'" + user.getLoginName() + "'失败，手机号码已存在");
        }
        else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
        {
            return error("新增用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
        }
        user.setSalt(ShiroUtils.randomSalt());
        user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
        user.setPwdUpdateDate(DateUtils.getNowDate());
        user.setCreateBy(getLoginName());
        return toAjax(userService.insertUser(user));
    }

    /**
     * 修改用户
     */
    @RequiresPermissions("system:user:edit")
    @GetMapping("/edit/{userId}")
    public String edit(@PathVariable("userId") Long userId, ModelMap mmap)
    {
        userService.checkUserDataScope(userId);
        List<SysRole> roles = roleService.selectRolesByUserId(userId);
        mmap.put("user", userService.selectUserById(userId));
        mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        mmap.put("posts", postService.selectPostsByUserId(userId));
        return prefix + "/edit";
    }

    /**
     * 查询用户详细
     */
    @RequiresPermissions("system:user:list")
    @GetMapping("/view/{userId}")
    public String view(@PathVariable("userId") Long userId, ModelMap mmap)
    {
        userService.checkUserDataScope(userId);
        mmap.put("user", userService.selectUserById(userId));
        mmap.put("roleGroup", userService.selectUserRoleGroup(userId));
        mmap.put("postGroup", userService.selectUserPostGroup(userId));
        return prefix + "/view";
    }

    /**
     * 修改保存用户
     */
    @RequiresPermissions("system:user:edit")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(@Validated SysUser user)
    {
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        deptService.checkDeptDataScope(user.getDeptId());
        roleService.checkRoleDataScope(user.getRoleIds());
        if (!userService.checkLoginNameUnique(user))
        {
            return error("修改用户'" + user.getLoginName() + "'失败，登录账号已存在");
        }
        else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
        {
            return error("修改用户'" + user.getLoginName() + "'失败，手机号码已存在");
        }
        else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
        {
            return error("修改用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
        }
        user.setUpdateBy(getLoginName());
        AuthorizationUtils.clearAllCachedAuthorizationInfo();
        return toAjax(userService.updateUser(user));
    }

    @RequiresPermissions("system:user:resetPwd")
    @GetMapping("/resetPwd/{userId}")
    public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap)
    {
        userService.checkUserDataScope(userId);
        mmap.put("user", userService.selectUserById(userId));
        return prefix + "/resetPwd";
    }

    @RequiresPermissions("system:user:resetPwd")
    @Log(title = "重置密码", businessType = BusinessType.UPDATE)
    @PostMapping("/resetPwd")
    @ResponseBody
    public AjaxResult resetPwdSave(SysUser user)
    {
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        user.setSalt(ShiroUtils.randomSalt());
        user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
        if (userService.resetUserPwd(user) > 0)
        {
            if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue())
            {
                setSysUser(userService.selectUserById(user.getUserId()));
            }
            return success();
        }
        return error();
    }

    /**
     * 进入授权角色页
     */
    @RequiresPermissions("system:user:edit")
    @GetMapping("/authRole/{userId}")
    public String authRole(@PathVariable("userId") Long userId, ModelMap mmap)
    {
        userService.checkUserDataScope(userId);
        SysUser user = userService.selectUserById(userId);
        // 获取用户所属的角色列表
        List<SysRole> roles = roleService.selectRolesByUserId(userId);
        mmap.put("user", user);
        mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        return prefix + "/authRole";
    }

    /**
     * 用户授权角色
     */
    @RequiresPermissions("system:user:edit")
    @Log(title = "用户管理", businessType = BusinessType.GRANT)
    @PostMapping("/authRole/insertAuthRole")
    @ResponseBody
    public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
    {
        userService.checkUserDataScope(userId);
        roleService.checkRoleDataScope(roleIds);
        userService.insertUserAuth(userId, roleIds);
        AuthorizationUtils.clearAllCachedAuthorizationInfo();
        return success();
    }

    @RequiresPermissions("system:user:remove")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        if (ArrayUtils.contains(Convert.toLongArray(ids), getUserId()))
        {
            return error("当前用户不能删除");
        }
        return toAjax(userService.deleteUserByIds(ids));
    }

    /**
     * 校验用户名
     */
    @PostMapping("/checkLoginNameUnique")
    @ResponseBody
    public boolean checkLoginNameUnique(SysUser user)
    {
        return userService.checkLoginNameUnique(user);
    }

    /**
     * 校验手机号码
     */
    @PostMapping("/checkPhoneUnique")
    @ResponseBody
    public boolean checkPhoneUnique(SysUser user)
    {
        return userService.checkPhoneUnique(user);
    }

    /**
     * 校验email邮箱
     */
    @PostMapping("/checkEmailUnique")
    @ResponseBody
    public boolean checkEmailUnique(SysUser user)
    {
        return userService.checkEmailUnique(user);
    }

    /**
     * 用户状态修改
     */
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @RequiresPermissions("system:user:edit")
    @PostMapping("/changeStatus")
    @ResponseBody
    public AjaxResult changeStatus(SysUser user)
    {
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        return toAjax(userService.changeStatus(user));
    }

    /**
     * 加载部门列表树
     */
    @RequiresPermissions("system:user:list")
    @GetMapping("/deptTreeData")
    @ResponseBody
    public List<Ztree> deptTreeData()
    {
        List<Ztree> ztrees = deptService.selectDeptTree(new SysDept());
        return ztrees;
    }

    /**
     * 选择部门树
     * 
     * @param deptId 部门ID
     */
    @RequiresPermissions("system:user:list")
    @GetMapping("/selectDeptTree/{deptId}")
    public String selectDeptTree(@PathVariable("deptId") Long deptId, ModelMap mmap)
    {
        mmap.put("dept", deptService.selectDeptById(deptId));
        return prefix + "/deptTree";
    }

    @RequiresPermissions("system:user:view")
    @GetMapping("/importHosTemplate")
    @ResponseBody
    public AjaxResult importHosTemplate()
    {
        ExcelUtil<HospitalImportDto> util = new ExcelUtil<HospitalImportDto>(HospitalImportDto.class);
        return util.importTemplateExcel("医院数据模板");
    }

    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
    @RequiresPermissions("system:user:import")
    @PostMapping("/importHosData")
    @ResponseBody
    public AjaxResult importHosData(MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<HospitalImportDto> util = new ExcelUtil<HospitalImportDto>(HospitalImportDto.class);
        List<HospitalImportDto> hospitalImportDtoList = util.importExcel(file.getInputStream());

        checkDeptLevels(hospitalImportDtoList);

        SysRole sysRole = getOrCreateSysRole();

        // 异常信息
        StringBuilder msg = new StringBuilder();
        for (HospitalImportDto item : hospitalImportDtoList) {
            // 部门
            SysDept sysDept = new SysDept();

            // 部门一级
            String dept1 = item.getDept1();
            if (StringUtils.isNotEmpty(dept1)) {
                SysDept sysDeptIn1 = new SysDept();
                sysDeptIn1.setParentId(0L);
                sysDeptIn1.setDeptName(dept1);
                List<SysDept> sysDepts1 = deptService.selectDeptList(sysDeptIn1);
                if (sysDepts1.size() > 0) {
                    sysDept = sysDepts1.get(0);
                } else {
                    SysDept sysDept1 = new SysDept();
                    sysDept1.setParentId(0L);
                    sysDept1.setDeptName(dept1);
                    sysDept1.setOrderNum(0);
                    sysDept1.setStatus("0");
                    deptService.insertDept(sysDept1);
                    sysDept = sysDept1;
                }
            }

            // 部门二级
            String dept2 = item.getDept2();
            if (StringUtils.isNotEmpty(dept2)) {
                sysDept = getOrCreateSysDept(dept2,sysDept);
            }

            // 部门二级
            String dept3 = item.getDept3();
            if (StringUtils.isNotEmpty(dept3)) {
                sysDept = getOrCreateSysDept(dept3,sysDept);
            }

            // 部门四级
            String dept4 = item.getDept4();
            if (StringUtils.isNotEmpty(dept4)) {
                sysDept = getOrCreateSysDept(dept4, sysDept);
            }

            // 部门五级
            String dept5 = item.getDept5();
            if (StringUtils.isNotEmpty(dept5)) {
                sysDept = getOrCreateSysDept(dept5, sysDept);
            }

            // 用户创建
            SysUser sysUser = userService.selectUserByLoginName(item.getHospitalId());
            if (null == sysUser) {
                sysUser = new SysUser();
                sysUser.setDeptId(sysDept.getDeptId());
                sysUser.setUserName(item.getHospitalName());
                sysUser.setLoginName(item.getHospitalId());
                sysUser.setPhonenumber(item.getPhone());
                sysUser.setUserType("00");
                sysUser.setSalt(ShiroUtils.randomSalt());
                sysUser.setPassword(passwordService.encryptPassword(sysUser.getLoginName(), StringUtils.isEmpty(item.getPassword()) ? "Bsoft@123456" : item.getPassword(), sysUser.getSalt()));
                sysUser.setRemark(item.getHospitalName() + "-表单导入");
                userService.insertUser(sysUser);
            } else {
//                msg = msg.append(sysUser.getLoginName() + "已存在，跳过导入;\n");
//                continue;
            }

            // 用户 角色 绑定
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(sysUser.getUserId());
            sysUserRole.setRoleId(sysRole.getRoleId());
            List<SysUserRole> sysUserRoles = userRoleService.selectSysUserRoleList(sysUserRole);
            if (null == sysUserRoles || sysUserRoles.size() <= 0) {
                userRoleService.insertSysUserRole(sysUserRole);
            }
        }
        return AjaxResult.success(msg);
    }

    /**
     * 部门断级 校验
     * @param hospitalImportDtoList
     */
    public void checkDeptLevels(List<HospitalImportDto> hospitalImportDtoList) {
        for (HospitalImportDto item : hospitalImportDtoList) {
            String[] deptLevels = {item.getDept1(), item.getDept2(), item.getDept3(), item.getDept4(), item.getDept5()};
            boolean hasNonNullDept = false;
            for (int i = 0; i < deptLevels.length; i++) {
                String currentDept = deptLevels[i];
                int level = i + 1;
                boolean currentHasValue = currentDept != null && !currentDept.trim().isEmpty();
                if (currentHasValue) {
                    hasNonNullDept = true;

                    if (i == 0) {
//                        throw new IllegalArgumentException("部门层级不连续，第" + level + "级为空但前序层级存在值");
                    } else {
                        String preStr = deptLevels[i-1];
                        boolean preHasValue = preStr != null && !preStr.trim().isEmpty();
                        if (!preHasValue) {
                            throw new IllegalArgumentException("部门层级不连续，第" + level + "级为空但前序层级存在值");
                        }
                    }
                }
            }
        }
    }

    public SysDept getOrCreateSysDept(String deptName, SysDept parentDept) {
        SysDept sysDept = parentDept;
        if (StringUtils.isNotEmpty(deptName)) {
            SysDept sysDeptIn2 = new SysDept();
            sysDeptIn2.setParentId(parentDept.getDeptId());
            sysDeptIn2.setDeptName(deptName);
            List<SysDept> sysDepts2 = deptService.selectDeptList(sysDeptIn2);
            if (sysDepts2.size() > 0) {
                sysDept = sysDepts2.get(0);
            } else {
                SysDept sysDept2 = new SysDept();
                sysDept2.setParentId(parentDept.getDeptId());
                sysDept2.setDeptName(deptName);
                sysDept2.setOrderNum(0);
                sysDept2.setStatus("0");
                deptService.insertDept(sysDept2);
                System.out.println(sysDept2.getDeptId());
//                deptService.insertDept()
                sysDept = sysDept2;
            }
        }
        return sysDept;
    }

    public SysRole getOrCreateSysRole() {
        SysRole sysRoleIn = new SysRole();
        sysRoleIn.setRoleKey("network");
        List<SysRole> roles = roleService.selectRoleList(sysRoleIn);
        if (roles.size() > 0) {
            return roles.get(0);
        } else {
            throw new RuntimeException("角色不存在");
        }

        /*SysRole sysRole = new SysRole();
        sysRole.setRoleKey("network");
        sysRole.setRoleName("网络测试");
        sysRole.setRoleSort("3");
        sysRole.setDataScope("5");
        sysRole.setStatus("0");
        sysRole.setRemark("网络测试");
        roleService.insertRole(sysRole);
        return sysRole;*/
    }



}